/*
 * Niiuzu
 * Copyright (C) 2011  Thierry Nowak
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.niiuzu.client.screen.feed.remove.channel;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.inject.Inject;
import com.mvp4g.client.annotation.Presenter;
import com.mvp4g.client.presenter.LazyPresenter;
import com.niiuzu.client.eventbus.FeedEventBus;
import com.niiuzu.client.i18n.FeedMessages;
import com.niiuzu.client.util.ClientContextFactory;
import com.niiuzu.client.util.LoadingTicket;
import com.niiuzu.client.util.SessionClient;
import com.niiuzu.client.util.callback.AbstractCallback;
import com.niiuzu.shared.model.FeedChannel;
import com.niiuzu.shared.model.FeedChannelGroup;
import com.niiuzu.shared.rpc.FeedServiceAsync;

/**
 * Presenter destiné à la suppression des flux et des thèmes.
 */
@Presenter(view = RemoveChannelViewImpl.class)
public class RemoveChannelPresenter extends
		LazyPresenter<RemoveChannelView, FeedEventBus> {

	@Inject
	private FeedServiceAsync feedService;

	private FeedChannel selectedChannel;

	private ClickHandler closeClickHandler;
	private ClickHandler confirmChannelRemoveClickHandler;
	private ClickHandler confirmGroupRemoveClickHandler;

	private FeedMessages feedMessages = GWT.create(FeedMessages.class);

	@Override
	public void bindView() {
		super.bindView();

		closeClickHandler = new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				view.hidePopup();
			}
		};
		view.getCloseButtonHasClickHandlers()
				.addClickHandler(closeClickHandler);
		view.getCancelHasClickHandlers().addClickHandler(closeClickHandler);

		confirmChannelRemoveClickHandler = new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				requestChannelRemove();
			}
		};
		view.getConfirmChannelRemoveHasClickHandlers().addClickHandler(
				confirmChannelRemoveClickHandler);

		confirmGroupRemoveClickHandler = new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				requestChannelGroupRemove();
			}
		};
		view.getConfirmGroupRemoveHasClickHandlers().addClickHandler(
				confirmGroupRemoveClickHandler);
	}

	/**
	 * Demande la suppression du flux côté serveur.
	 */
	private void requestChannelRemove() {

		String loadingMessage = feedMessages.removingChannelMessage();
		final LoadingTicket ticket = LoadingTicket.Factory.createTicket(
				getClass(), loadingMessage);

		eventBus.loadingStarted(ticket);

		feedService.removeChannel(selectedChannel, ClientContextFactory.get(),
				new AbstractCallback<Void>(eventBus, ticket) {
					@Override
					public void onSuccess(Void result) {
						removeChannelOnClientSide(selectedChannel, ticket);
					}
				});
	}

	/**
	 * Demande la suppression du thème côté serveur.
	 */
	private void requestChannelGroupRemove() {

		SessionClient sessionClient = SessionClient.getInstance();

		// Récupère le thème du flux
		final FeedChannelGroup channelGroup;
		channelGroup = sessionClient.getGroupFromChannel(selectedChannel);

		String loadingMessage = feedMessages.removingChannelGroupMessage();
		final LoadingTicket ticket = LoadingTicket.Factory.createTicket(
				getClass(), loadingMessage);

		eventBus.loadingStarted(ticket);

		feedService.removeChannelGroup(channelGroup,
				ClientContextFactory.get(), new AbstractCallback<Void>(
						eventBus, ticket) {
					@Override
					public void onSuccess(Void result) {
						removeChannelGroupOnClientSide(channelGroup, ticket);
					}
				});
	}

	/**
	 * Supprime le flux côté client.
	 * 
	 * @param channel
	 *            flux à supprimer.
	 * @param ticket
	 *            ticket correspondant à la suppression côté serveur.
	 */
	void removeChannelOnClientSide(FeedChannel channel, LoadingTicket ticket) {

		SessionClient.getInstance().removeChannel(channel);

		view.hidePopup();
		eventBus.channelsRemoved();
		eventBus.loadingFinished(ticket);
	}

	/**
	 * Supprime le thème et les flux qui lui sont liés côté client.
	 * 
	 * @param channelGroup
	 *            thèmes à supprimer.
	 * @param ticket
	 *            ticket correspondant à la suppression côté serveur.
	 */
	void removeChannelGroupOnClientSide(FeedChannelGroup channelGroup,
			LoadingTicket ticket) {

		SessionClient sessionClient = SessionClient.getInstance();

		// Supprime tous les flux liés au thème récupéré
		FeedChannel[] linkedChannels;
		linkedChannels = sessionClient.getChannelsFromGroup(channelGroup);
		for (FeedChannel channel : linkedChannels) {
			sessionClient.removeChannel(channel);
		}
		// Supprime le thème
		sessionClient.removeChannelGroup(channelGroup);

		view.hidePopup();
		eventBus.channelsRemoved();
		eventBus.loadingFinished(ticket);
	}

	/**
	 * Une demande de suppression d'un flux ou d'un thème a été détectée.
	 * 
	 * @see FeedEventBus#channelOrGroupRemoveAsked(FeedChannel)
	 */
	public void onChannelOrGroupRemoveAsked(FeedChannel channel) {
		this.selectedChannel = channel;

		FeedChannelGroup channelGroup = SessionClient.getInstance()
				.getGroupFromChannel(selectedChannel);

		view.initViewWith(channel.getName(), channelGroup.getName());
		view.showPopup();
	}

	/**
	 * Comportement déclenché à la demande de fermeture de la popup.
	 */
	public ClickHandler getCloseClickHandler() {
		return closeClickHandler;
	}

	/**
	 * Comportement lié aux clics sur le bouton de confirmation de suppression
	 * du flux.
	 */
	public ClickHandler getConfirmChannelRemoveClickHandler() {
		return confirmChannelRemoveClickHandler;
	}

	/**
	 * Comportement lié aux clics sur le bouton de confirmation de suppression
	 * du thème.
	 */
	public ClickHandler getConfirmGroupRemoveClickHandler() {
		return confirmGroupRemoveClickHandler;
	}

	/* ********************************************************************** */
	/* ********************************************************************** */
	/* ********************************************************************** */

	/**
	 * JUnit - Définit un mock pour {@link FeedServiceAsync}.
	 */
	void setMockedFeedService(FeedServiceAsync mockedFeedService) {
		this.feedService = mockedFeedService;
	}

	/**
	 * JUnit - Définit un mock pour {@link FeedMessages}.
	 */
	void setMockedFeedMessages(FeedMessages mockedFeedMessages) {
		this.feedMessages = mockedFeedMessages;
	}

}
